// 该页面为博客列表页面，已归类到 blog 目录
<script setup lang="ts">
  import TableSearch from '@/components/common/TableSearch.vue'
  import TableCustom from '@/components/common/TableCustom.vue'
  import { reactive, ref } from 'vue'
  import { FormOption, TableColumns } from '@/types/form-option.ts'
  import { page, push, remove, statusChange, top } from '@/api/blog.ts'
  import { Blog, BlogPageParam, Category } from '@/types'
  import { ElMessage } from 'element-plus'
  import {
    CirclePlusFilled,
    Delete,
    Edit,
    Finished,
    Top,
    View,
    Picture,
  } from '@element-plus/icons-vue'
  import BlogMarkdown from '@/views/blog/blog-list/components/BlogMarkdown.vue'
  import { ElImageViewer } from 'element-plus'
  import { buildBlogVectorStore } from '@/api/ai'

  const searchOpt = ref<FormOption[]>([
    { type: 'input', label: '关键字：', prop: 'keyword' },
    {
      type: 'select',
      label: '状态：',
      prop: 'status',
      options: [
        { label: '全部', value: '' },
        { label: '初始', value: '0' },
        { label: '上架', value: '1' },
        { label: '隐藏', value: '2' },
      ],
    },
  ])

  // 表格字段配置
  const columns = ref<TableColumns[]>([
    { type: 'index', prop: '', label: '序号', width: 55, align: 'center' },
    { prop: 'title', label: '标题', width: 200 },
    { prop: 'backgroundImg', label: '背景图', width: 120 },
    { prop: 'tags', label: '标签' },
    {
      prop: 'categories',
      label: '分类',
      formatter: (cellValue: unknown) => {
        if (!Array.isArray(cellValue)) return ''
        return (cellValue as Category[]).map(item => item?.name ?? '').join(' / ')
      },
    },
    { prop: 'topFlag', label: '置顶标记' },
    { prop: 'status', label: '状态' },
    { prop: 'operator', label: '操作', width: 400 },
  ])

  const param = reactive<BlogPageParam>({
    keyword: '',
    status: '',
    pageNum: 1,
    pageSize: 10,
  })

  const visible = ref(false)

  const isEdit = ref(false)
  const rowData = ref()

  // 图片预览相关
  const previewVisible = ref(false)
  const previewImageList = ref<string[]>([])
  //表格数据
  const tableData = ref<Blog[]>([])
  //总数
  const total = ref(0)

  //搜索方法
  const handleSearch = () => {
    changePage(1)
  }

  const handleAdd = () => {
    rowData.value = {}
    visible.value = true
    isEdit.value = false
  }
  const handleEdit = (row: Blog) => {
    rowData.value = { ...row }
    visible.value = true
    isEdit.value = true
  }
  const handleView = (row: Blog) => {
    window.open('/blog-view' + '?id=' + row.id)
  }
  const handleChangeStatus = async (row: Blog) => {
    let message = '发布成功'
    switch (row.status) {
      case 0:
        await push({ id: row.id })
        message = '发布成功'
        break
      case 1:
        await statusChange({ id: row.id, status: 2 })
        message = '修改成功'
        break
      case 2:
        await statusChange({ id: row.id, status: 1 })
        message = '修改成功'
        break
      default:
        ElMessage.error('未知的博客状态：' + row.status)
        return
    }
    ElMessage.success(message)
    await getData()
  }
  const handleTop = async (row: Blog) => {
    if (row.topFlag === 0) {
      await top({ id: row.id, topFlag: 1 })
    } else {
      await top({ id: row.id, topFlag: 0 })
    }
    ElMessage.success('保存成功')
    await getData()
  }
  const handleDelete = async (row: Blog) => {
    await remove({ id: row.id })
    ElMessage.success('删除成功')
    await getData()
  }

  // 构建知识库
  const handleBuildVectorStore = async () => {
    try {
      await buildBlogVectorStore()
      ElMessage.success('知识库构建成功')
    } catch (e) {
      ElMessage.error('知识库构建失败')
      console.error(e)
    }
  }

  const changePage = (val: number) => {
    param.pageNum = val
    getData()
  }

  //查询分页
  const getData = async () => {
    const data = await page(param)
    tableData.value = data.records
    total.value = data.total
  }

  const closeDialog = () => {
    visible.value = false
    isEdit.value = false
    getData()
  }

  // 处理图片预览
  const handlePreview = (url: string) => {
    previewImageList.value = [`/api/file/${url}`]
    previewVisible.value = true
  }

  getData()
</script>

<template>
  <div>
    <!--  搜索栏  -->
    <TableSearch :query="param" :options="searchOpt" :search="handleSearch" />
    <div class="container">
      <!--表格-->
      <TableCustom
        :columns="columns"
        :table-data="tableData"
        :total="total"
        :page-size="param.pageSize"
        :current-page="param.pageNum"
        :del-func="handleDelete"
        :edit-func="handleEdit"
        :view-func="handleView"
        :change-page="changePage"
      >
        <template #toolbarBtn>
          <el-button type="primary" @click="handleBuildVectorStore">构建知识库</el-button>
          <el-button type="warning" :icon="CirclePlusFilled" @click="handleAdd">新增</el-button>
        </template>
        <template #title="{ row }">
          <el-tooltip effect="light">
            <template #content>
              <span style="max-width: 500px">{{ row.summary }}</span>
            </template>
            <span>{{ row.title }}</span>
          </el-tooltip>
        </template>
        <template #backgroundImg="{ row }">
          <el-image
            v-if="row.backgroundImg"
            :src="`/api/file/${row.backgroundImg}`"
            fit="cover"
            style="width: 100px; height: 60px; border-radius: 4px; cursor: pointer"
            lazy
            @click="handlePreview(row.backgroundImg)"
          >
            <template #error>
              <div class="image-slot">
                <el-icon><Picture /></el-icon>
              </div>
            </template>
          </el-image>
          <span v-else style="color: #909399">无</span>
        </template>
        <template #tags="{ row }">
          <el-tag v-for="tag in row.tags" :key="tag.id" type="info">
            {{ tag.name }}
          </el-tag>
        </template>
        <template #topFlag="{ row }">
          <el-tag v-if="row.topFlag == 1" type="success">是</el-tag>
          <el-tag v-else type="info">否</el-tag>
        </template>
        <template #status="{ row }">
          <el-tag v-if="row.status == 0" type="info">初始</el-tag>
          <el-tag v-else-if="row.status == 1" type="success">上架</el-tag>
          <el-tag v-else type="danger">隐藏</el-tag>
        </template>
        <template #operator="{ row }">
          <el-button type="warning" size="small" :icon="View" @click="handleView(row)">
            查看
          </el-button>
          <el-button type="primary" size="small" :icon="Edit" @click="handleEdit(row)">
            编辑
          </el-button>
          <el-button type="warning" size="small" :icon="Finished" @click="handleChangeStatus(row)">
            {{ row.status === 0 ? '发布' : row.status === 1 ? '隐藏' : '恢复' }}
          </el-button>
          <el-button type="warning" size="small" :icon="Top" @click="handleTop(row)">
            {{ row.topFlag === 0 ? '置顶' : '取消' }}
          </el-button>
          <el-button type="danger" size="small" :icon="Delete" @click="handleDelete(row)">
            删除
          </el-button>
        </template>
      </TableCustom>
    </div>
    <el-dialog
      v-model="visible"
      :title="isEdit ? '编辑' : '新增'"
      width="100%"
      :fullscreen="true"
      destroy-on-close
      :show-close="false"
      :close-on-click-modal="false"
      @close="closeDialog"
    >
      <template #header>
        <div class="dialog-header">
          <el-page-header @back="closeDialog" />
        </div>
      </template>
      <BlogMarkdown :close="closeDialog" :data="rowData" />
    </el-dialog>

    <!-- 图片预览 -->
    <ElImageViewer
      v-if="previewVisible"
      :url-list="previewImageList"
      :hide-on-click-modal="true"
      :teleported="true"
      :z-index="2000"
      @close="previewVisible = false"
    />
  </div>
</template>

<style scoped>
  /*noinspection CssUnusedSymbol*/
  :deep(.view-header-div .el-icon) {
    position: fixed;
    right: 120px;
    bottom: 60px;
    font-size: 30px;
    color: gray;
    cursor: pointer;
  }

  .dialog-header {
    margin: 5px;
  }

  .image-slot {
    display: flex;
    justify-content: center;
    align-items: center;
    width: 100%;
    height: 100%;
    background: #f5f7fa;
    color: #909399;
    font-size: 24px;
  }
</style>
